package cloudspace.ui.applet;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;


public class AppletProxyFactory
{
    public static CtClass generateProxy(
        CtClass toProxy,
        CtClass toExec,
        ClassPool pool )
    {
        try
        {
            CtClass proxy = pool.makeClass( "_Proxy_" + toProxy.getSimpleName() );
            for ( CtMethod method : toProxy.getMethods() )
            {
                if ( Modifier.isPrivate( method.getModifiers() )
                    || Modifier.isProtected( method.getModifiers() ) )
                    continue;
                String methodName = method.getName();
                CtClass[] parameters = method.getParameterTypes();
                CtClass[] exParameters = new CtClass[parameters.length + 1];
                exParameters[0] = pool.get( "java.lang.Object" );
                for ( int i = 0; i < parameters.length; i++ )
                    exParameters[i + 1] = parameters[i];
                CtClass returnType = method.getReturnType();
                CtClass[] exceptions = method.getExceptionTypes();
                CtMethod proxyMethod = new CtMethod( returnType,
                    methodName,
                    exParameters,
                    proxy );
                proxyMethod.setModifiers( Modifier.PUBLIC | Modifier.STATIC );
                proxyMethod.setExceptionTypes( exceptions );
                String body = "";
                if ( !returnType.equals( CtClass.voidType ) )
                    body += "return ";
                body += "((" + toExec.getName() + ")$1)." + methodName + "(";
                for ( int i = 0; i < parameters.length; i++ )
                {
                    body += "$" + ( i + 2 );
                    if ( i != parameters.length - 1 )
                    {
                        body += ",";
                    }
                }
                body += ");";
                proxyMethod.setBody( body );
                proxy.addMethod( proxyMethod );
            }
            return proxy;
        }
        catch ( NotFoundException e )
        {
            e.printStackTrace();
        }
        catch ( CannotCompileException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}
